//
// Created by jsjxsy on 2022/7/5.
//
#include <stdio.h>
#include<string.h>

/* 声明雇主编码函数 bian1 和雇员编码函数 bian2 以及雇员解码函数jie */

void bian1(char *, int *, int);
void bian2(char *, int *, int);
void jie(int *, int, int *(*p)(int *, int));

/* 定义雇员和雇主结构体，将不同的功能封装到对应的结构体中 */

typedef struct {
  int num;
  char a[15];
  int b[15];
  void (*code)(char *, int *, int);//= bain1;
} employer;

typedef struct {
  int num;
  char a[15];
  int b[15];
  void (*decode)(int *, int, int *(*p)(int *, int));// = jie
  void (*code)(char *, int *, int);//= bian2
} employee;

/* 采用冒泡排序的方法进行解码排序 */

int *rise(int *a, int len) {
  int t;
  for (int i = 0; i < len; i++) {
    for (int j = 0; j < len - 1 - i; j++)
      if (a[j] > a[j + 1]) {
        t = a[j];
        a[j] = a[j + 1];
        a[j + 1] = t;
      }
  }
  return a;
}

int *fall(int *a, int len) {
  int t;
  for (int i = 0; i < len; i++) {
    for (int j = 0; j < len - 1 - i; j++)
      if (a[j] < a[j + 1]) {
        t = a[j];
        a[j] = a[j + 1];
        a[j + 1] = t;
      }
  }
  return a;
}

/* 选择合适的解码排序方式，并将其赋值给函数指针，函数指针在解码函数中发挥作用 */

void jie(int *a, int len, int *(*p)(int *, int)) {
  a = (*p)(a, len - 1);
  for (int i = 0; i < len - 1; i++) {
    a[i] = a[i] - 50;                //雇员解码方式，先排序在给每个数组元素减 50
  }
}

void bian1(char *a, int *b, int len) {
  for (int i = 0; i < len - 1; i++) {
    b[i] = a[i] - '0' + 50;          //雇主编码方式，字符转化为整型数据并加 50
  }
  b[len - 1] = a[len - 1];
}

void bian2(char *a, int *b, int len) {
  for (int i = 0; i < len - 1; i++) {
    a[i] = b[i] + 48;                //雇员编码方式，整型数据转化为字符
  }
  a[len - 1] = b[len - 1];
}

int main() {
  employer boss1;                      //定义两个结构体 boss 和 staff
  boss1.code = bian1;
  employee staff1;
  staff1.code=bian2;
  staff1.decode=jie;
  int len = 0;
  printf("请输入编码：");               //boss输入编码到编码数组 a
  scanf("%s", boss1.a);
  len = strlen(boss1.a);
  printf("编码长度: %d\n", len);
  boss1.code(boss1.a, boss1.b, len);
  printf("编码结果为：");               //boss编码结果输出到编码数组 b 中并输出展示
  for (int i = 0; i < len - 1; i++) {
    printf("%d", boss1.b[i]);
  }
  printf("\n");
  printf("正在将编码发给雇员，请稍后……");
  printf("\n");
  for (int i = 0; i < len; i++) {
    staff1.b[i] = boss1.b[i];        //boss的编码结果一个个赋值到 staff 解码数组 b中
  }
  switch (staff1.b[len - 1])              //通过判断最后一位数据来确定解码方式
  {
    case 'r': staff1.decode(staff1.b, len, rise);
      break;
    case 'f': staff1.decode(staff1.b, len, fall);
      break;
  }
  printf("雇员解码结果为：");
  for (int i = 0; i < len - 1; i++) {
    printf("%d", staff1.b[i]);        //输出解码结果
  }
  printf("\n");
  staff1.code(staff1.a, staff1.b, len); //通过 staff 解码数组重新编码后放到编码数组 a 中
  printf("雇员编码为：");
  printf("%s\n", staff1.a);
  return 0;
}



